package com.ls.demo.pattern.singleton;

/**
 * 〈〉
 *
 * @author ls
 * @create 2021-11-23 14:28:12
 * @return
 */
public class LazyDoubleCheckSingleton {
    private volatile static LazyDoubleCheckSingleton instance;
    private LazyDoubleCheckSingleton(){}

    /**
     * 两次判空的目的
     *   从运行结果可以看出，如果不进行第二次判空的话，那么在竟锁池(锁池)中如果还有活跃的线程在等待获取的锁的话，在锁释放后就会再次竞争获取锁，获取的锁的线程进入"就绪状态"，
     *   当cpu分配其"时间片"后进行线程的调度，从而线程进入"运行中状态"，并会去执行同步的代码块，如果在没加如二次判空的话，就会导致系统中存在多个实例，而在进行判空后，即使你获取到了锁，但在执行同步代码块时也会直接跳过。
     * 　如果不判空的话,会出现多个线程在等待获取当前的锁,当其中的一个线程释放掉锁后,又会重新new 一个对象.就会出现不同的对象
     * @return
     */
    public static LazyDoubleCheckSingleton getInstance(){
        //第一次检查
        if(instance == null){
            //同步
            synchronized (LazyDoubleCheckSingleton.class){
                if(instance == null){
                    //分配对象内存空间
                    //初始化对象
                    //设置instance只想刚分配的地址
                    instance = new LazyDoubleCheckSingleton();
                }
            }
        }
        return instance;
    }
}